package com.yanqu.road.server.manager.union;

import com.yanqu.road.entity.enums.eUnionSyncType;
import com.yanqu.road.entity.player.CrossUserBaseInfo;
import com.yanqu.road.entity.union.UnionJoinApply;
import com.yanqu.road.entity.union.cross.CrossUnionInfo;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.CrossUnionPb;
import com.yanqu.road.pb.union.UnionProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.rank.CrossGroupUserMonthAbilityRankMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manger.CrossUnionServerGroupMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.string.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossUnionJoinApplyMgr extends TempMgr {

    private static Map<String, Map<Long, UnionJoinApply>> unionJoinApplyMap = new ConcurrentHashMap<>();

    @Override
    public boolean reloadData() {
        unionJoinApplyMap = new ConcurrentHashMap<>();
        return true;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        if (unionJoinApplyMap == null) {
            unionJoinApplyMap = new ConcurrentHashMap<>();
        }
        Iterator<Map.Entry<String, Map<Long, UnionJoinApply>>> iterator = unionJoinApplyMap.entrySet().iterator();
        long now = System.currentTimeMillis() / 1000;
        while (iterator.hasNext()) {
            Map.Entry<String, Map<Long, UnionJoinApply>> entry = iterator.next();
            Map<Long, UnionJoinApply> applyMap = entry.getValue();
            Iterator<Map.Entry<Long, UnionJoinApply>> entryIterator = applyMap.entrySet().iterator();
            while (entryIterator.hasNext()) {
                Map.Entry<Long, UnionJoinApply> applyEntry = entryIterator.next();
                UnionJoinApply apply = applyEntry.getValue();
                if (apply.isDelete() && apply.getApplyTime() < now) {
                    //过期了 移除
                    entryIterator.remove();
                }
            }
        }
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    public static int addUnionJoinApply(CrossUserBaseInfo player, String unionUid) {
        long serverId = player.getUserBaseInfo().getServerId();
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)) {
            if (!unionJoinApplyMap.containsKey(unionUid)) {
                unionJoinApplyMap.put(unionUid, new ConcurrentHashMap<>());
            }
            Map<Long, UnionJoinApply> applyMap = getUnionJoinApplyMap(unionUid);

            int size = 0;
            long now = System.currentTimeMillis()/1000;
            for (UnionJoinApply apply : applyMap.values()) {
                if (apply.isDelete() || apply.getApplyTime() > now) {
                    continue;
                }
                if (apply.getUserId() == player.getUserId()) {
                    return GameErrorCode.E_UNION_JOIN_APPLY_EXIST;
                }
                size++;
            }
            if (size >= GameConfig.UNION_JOIN_APPLY_MAX_COUNT) {
                return GameErrorCode.E_UNION_JOIN_APPLY_FULL;
            }

            UnionJoinApply apply = applyMap.get(player.getUserId());
            if (apply != null) {
                long applyTime = apply.getApplyTime();
                if (applyTime > now) {
                    return GameErrorCode.E_UNION_APPLY_OFTEN;
                }
            }

            CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
            if (null == unionInfo) {
                return GameErrorCode.E_UNION_NO_FOUND;
            }

            if(!unionInfo.isCross() && unionInfo.getServerId() != player.getUserBaseInfo().getServerId()){
                return GameErrorCode.E_UNION_JOIN_APPLY_MUST_IN_SAME_GROUP;
            }

            int groupId = CrossUnionServerGroupMgr.getGroupIdByServerId(serverId);

            Set<Long> serverSet = CrossUnionServerGroupMgr.getGroupServer(groupId);
            if (!serverSet.contains(unionInfo.getServerId())) {
                return GameErrorCode.E_UNION_JOIN_APPLY_MUST_IN_SAME_GROUP;
            }
            int crossServerCount = CrossUnionServerGroupMgr.getGroupServerCountByServerId(unionInfo.getServerId());
            if (CrossUnionMgr.getUnionMemberCount(unionUid) >= CrossUnionConfigMgr.getMaxMemberCount(unionInfo.getExperience(), unionInfo.isCross(), crossServerCount)) {
                return GameErrorCode.E_UNION_MEMBER_FULL;
            }

            String ownUnionUid = player.getUserBaseInfo().getUnionUid();
            CrossUnionMember unionMember = CrossUnionMgr.getUnionMemberByUserId(player.getUserId());
            if (unionMember != null) {//身上的商会id以member为准
                ownUnionUid = unionMember.getUnionUid();
            } else {
                ownUnionUid = "";
            }
            if (!StringUtils.isNullOrEmpty(ownUnionUid)) {
                return GameErrorCode.E_UNION_HAS_JOIN_UNION;
            }

            int applyTitleLimit = unionInfo.getApplyTitleLimit();
            if (player.getUserBaseInfo().getTitleId() < applyTitleLimit) {
                return GameErrorCode.E_UNION_APPLY_TITLE_LIMIT;
            }



            UnionJoinApply unionJoinApply = new UnionJoinApply();
            unionJoinApply.setUnionUid(unionUid);
            unionJoinApply.setUserId(player.getUserId());
            unionJoinApply.setApplyTime(System.currentTimeMillis() / 1000);


            unionJoinApply.setUserBaseInfo(player.getUserBaseInfo());

            CrossUnionMember member = CrossUnionMgr.getUnionMemberByUserId(unionJoinApply.getUserId());
            if (null != member) {
                CrossUnionMgr.checkUserMonthRankGrade(member.getServerId(), member.getUserId(), member.getHistoryMaxAbility());
                unionJoinApply.setRankGrade(member.getAbilityRankGrade());
            }

            applyMap.put(player.getUserId(), unionJoinApply);


            addApplyUnionUid(unionUid, player);
            //同步请求(给族长和副族长同步)
            syncJoinApply(unionUid, unionJoinApply);
        }
        return 0;
    }

    public static int agreeJoinApply(CrossUserBaseInfo player, String unionUid, long applyUserId) {
        long serverId = player.getUserBaseInfo().getServerId();
        synchronized (CrossUnionLockerMgr.getGourpLocker(serverId)){
            UnionJoinApply apply = CrossUnionJoinApplyMgr.getUnionJoinApply(unionUid, applyUserId);
            if(apply == null){
                return GameErrorCode.E_UNION_JOIN_APPLY_NO_FOUND;
            }
            CrossUserBaseInfo applyPlayer = CrossUserMgr.getCrossUserBaseInfo(applyUserId);
            CrossUnionMember applyMember = CrossUnionMgr.getUnionMemberByUserId(applyUserId);
            if(null != applyMember && !StringUtils.isNullOrEmpty(applyMember.getUnionUid())){
                return GameErrorCode.E_UNION_HAS_JOIN_UNION;
            }
            int result = CrossUnionMgr.addUnionMember(player, unionUid, applyUserId);
            if (0 == result) {
                removeJoinApply(unionUid, applyUserId);

                CrossUnionParergonMgr.sycnUserAllParergonData(applyPlayer);

                CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
                CrossUnionMgr.sendUnionChangeBroadcast(eUnionSyncType.JoinUnion.getValue(), unionInfo, player, null, applyUserId);

                List<CrossUnionMember> memberList = new ArrayList<>();
                CrossUnionMember unionMember = CrossUnionMgr.getUnionMember(unionInfo.getUnionUid(), applyUserId);
                if(unionMember != null) {
                    memberList.add(unionMember);
                    CrossUnionNotifyMgr.notifyListener(eUnionSyncType.JoinUnion.getValue(), player.getUserId(), unionInfo, memberList);
                }
            }
            return result;
        }
    }

    public static void removeAllJoinApply(String unionUid) {
        CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
        List<UnionJoinApply> syncList = new ArrayList<>();
        synchronized (CrossUnionLockerMgr.getGourpLocker(unionInfo.getServerId())) {
            Map<Long, UnionJoinApply> applyMap = getUnionJoinApplyMap(unionUid);
            if (null != applyMap) {
                for (UnionJoinApply apply : applyMap.values()) {
                    apply.setDelete(true);
                    // 加个30分钟
                    apply.setApplyTime(System.currentTimeMillis() / 1000 + GameConfig.PARERGON_JOIN_REFUSE_CD);
                    syncList.add(apply);
                }
                syncJoinApply(null, unionUid, syncList);
              //  unionJoinApplyMap.put(unionUid, new ConcurrentHashMap<>());
            }
        }
        for(UnionJoinApply apply : syncList) {
            //移除记录
            CrossUnionMember applyMember = CrossUnionMgr.getUnionMember("", apply.getUserId());
            if (null != applyMember) {
                applyMember.removeApplyUnionUid(unionUid);
                CrossUnionMgr.syncUnionMember(applyMember);
            }
        }
    }

    public static int removeJoinApply(String unionUid, long applyUserId) {
        CrossUnionInfo unionInfo = CrossUnionMgr.getUnionInfo(unionUid);
        synchronized (CrossUnionLockerMgr.getGourpLocker(unionInfo.getServerId())) {
            Map<Long, UnionJoinApply> applyMap = getUnionJoinApplyMap(unionUid);
            if(null == applyMap) {
                return GameErrorCode.E_UNION_JOIN_APPLY_NO_FOUND;
            }
            UnionJoinApply apply = applyMap.get(applyUserId);
            if(null == apply){
                return GameErrorCode.E_UNION_JOIN_APPLY_NO_FOUND;
            }
            apply.setDelete(true);
            long now = System.currentTimeMillis() / 1000;
            if (apply.getApplyTime() < now) {
                apply.setApplyTime(now + GameConfig.PARERGON_JOIN_REFUSE_CD);
            }
            syncJoinApply(unionUid, apply);
            //先不移除
            //applyMap.remove(applyUserId);
            //移除记录
            CrossUnionMember applyMember = CrossUnionMgr.getUnionMember("", applyUserId);
            if(null == applyMember){
                //UserInfo userInfo = UserMgr.getUserInfo(applyUserId);
                CrossUserBaseInfo userInfo = CrossUserMgr.getCrossUserBaseInfo(applyUserId);
                if(null != userInfo && !StringUtils.isNullOrEmpty(userInfo.getUserBaseInfo().getUnionUid())){
                    applyMember = CrossUnionMgr.getUnionMember(userInfo.getUserBaseInfo().getUnionUid(), applyUserId);
                    if(applyMember != null) {
                        applyMember.removeApplyUnionUid(unionUid);
                        //CrossUserBaseInfo applyPlayer = GamePlayerMgr.getOnlinePlayer(applyUserId);
                        //if (null != applyPlayer) {
                        //    applyPlayer.getModule(UnionModule.class).syncUnionMember(applyMember);
                        //}
                        CrossUnionMgr.syncUnionMember(applyMember);
                    }
                }
            }
//            if(null != applyMember) {
//                applyMember.removeApplyUnionUid(unionUid);
//                CrossUserBaseInfo applyPlayer = GamePlayerMgr.getOnlinePlayer(applyUserId);
//                if(null != applyPlayer){
//                    applyPlayer.getModule(UnionModule.class).syncUnionMember(applyMember);
//                }
//            }
            return 0;
        }

    }

    public static void sendJoinApplyList(CrossUserBaseInfo player, String unionUid) {
        Map<Long, UnionJoinApply> applyMap = getUnionJoinApplyMap(unionUid);
        if (null != applyMap) {
            syncJoinApply(player, unionUid, new ArrayList<>(applyMap.values()));
        }
    }

    public static void syncJoinApply(String unionUid, UnionJoinApply unionJoinApply){
        if(null != unionJoinApply){
            List<UnionJoinApply> syncList = new ArrayList<>();
            syncList.add(unionJoinApply);
            syncJoinApply(null, unionUid, syncList);
        }
    }

    public static void syncJoinApply(CrossUserBaseInfo player, String unionUid, List<UnionJoinApply> unionJoinApplyList){
        long now = System.currentTimeMillis() / 1000;
        ArrayList<UnionJoinApply> list = new ArrayList<>(unionJoinApplyList);
        List<UnionJoinApply> syncList = new ArrayList<>();
        for (UnionJoinApply apply : list) {
            long applyTime = apply.getApplyTime();
            if (applyTime > now + 3) {
                continue;
            }

            CrossUnionMember member = CrossUnionMgr.getUnionMemberByUserId(apply.getUserId());
            if (null != member) {
                CrossUnionMgr.checkUserMonthRankGrade(member.getServerId(), member.getUserId(), member.getHistoryMaxAbility());
                apply.setRankGrade(member.getAbilityRankGrade());
            }
            syncList.add(apply);
        }
        UnionProto.UnionJoinApplyListMsg.Builder msg = CrossUnionPb.parseUnionJoinApplyListMsg(syncList);
        if(null != player){
            MessageHelper.sendPacket(player.getUserBaseInfo().getServerId(), player.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_UNION_JOIN_APPLY_SYNC, msg));
        }else {
            Map<Long, CrossUnionMember> memberMap = CrossUnionMgr.getUnionMemberMap(unionUid);
            if(null != memberMap) {
                for (CrossUnionMember member : memberMap.values()) {
                    if(CrossUnionMgr.hasApplyPassRole(member)){
                        CrossUserBaseInfo onlinePlayer = CrossUserMgr.getCrossUserBaseInfo(member.getUserId());
                        if (null != onlinePlayer) {
                            MessageHelper.sendPacket(onlinePlayer.getUserBaseInfo().getServerId(), onlinePlayer.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_UNION_JOIN_APPLY_SYNC, msg));
                        }
                    }
                }
            }
        }
    }

    public static Map<Long, UnionJoinApply> getUnionJoinApplyMap(String unionUid){
        return unionJoinApplyMap.get(unionUid);
    }

    public static UnionJoinApply getUnionJoinApply(String unionUid, long applyUserId){
        Map<Long, UnionJoinApply> applyMap = getUnionJoinApplyMap(unionUid);
        if(null == applyMap) {
            return null;
        }
        return applyMap.get(applyUserId);
    }

    public static void addApplyUnionUid(String unionUid, CrossUserBaseInfo userBaseInfo){
        CrossUnionMember member = CrossUnionMgr.getUnionMember("", userBaseInfo.getUserId());
        if(null == member){
            member = new CrossUnionMember();
            member.setUnionUid("");
            member.setUserId(userBaseInfo.getUserId());
            member.setUserBaseInfo(userBaseInfo.getUserBaseInfo());
            member.setServerId(userBaseInfo.getUserBaseInfo().getServerId());
            member.setMonthAbilityRank(CrossGroupUserMonthAbilityRankMgr.getUserRank(member.getServerId(), member.getUserId()));

            member.setInsertOption();
            CrossUnionMgr.addMemberToDeleteMap(member);
        }
        member.addApplyUnionUid(unionUid);
        CrossUnionMgr.syncUnionMember(member);
    }
}
